﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

namespace FRL.DebtChased.Silverlight.Library.Controls
{
    public class SwapPanelController
    {

        #region Private Members
        /////////////////////////////////////////////////////////////
        // Private members

        private SwapPanelControllerParams[] controls { get; set; }

        private Storyboard sbOpenPanel;
        private Storyboard sbClosePanel;
        private Storyboard sbSwapPanels;
        DoubleAnimation animOpen;
        DoubleAnimation animClose;
        DoubleAnimation animSwapOpen;
        DoubleAnimation animSwapClose;

        private GridLength _gridRowHeightZero = new GridLength(0);
        private GridLength _gridRowHeightAuto = new GridLength(1, GridUnitType.Auto);
        private GridLength _gridRowHeightStar = new GridLength(1, GridUnitType.Star);


        private SwapPanelControllerParams activeControl;
        private SwapPanelControllerParams lastControl;

        #endregion

        #region Constructor
        /////////////////////////////////////////////////////////////
        // Constructor

        public SwapPanelController(SwapPanelControllerParams[] controls)
        {
            this.controls = controls;
            if (this.controls != null)
            {
                foreach (SwapPanelControllerParams control in this.controls)
                {
                    if (activeControl == null && control.headingCrtl.IsArrowUp)
                    {
                        activeControl = control;
                        control.userControl.Visibility = Visibility.Visible;
                        control.gridRow.Height = _gridRowHeightStar;
                    }
                    else
                    {
                        control.userControl.Visibility = Visibility.Collapsed;
                        control.gridRow.Height = _gridRowHeightAuto;
                        control.headingCrtl.IsArrowUp = false;
                    }
                    control.headingCrtl.ExpandChange += new EventHandler(headingCrtl_ExpandChange);
                }

                TimeSpan duration = TimeSpan.FromSeconds(0.4);

                animOpen = new DoubleAnimation();
                Storyboard.SetTargetProperty(animOpen, new PropertyPath("Height"));
                animOpen.Duration = new Duration(duration);
                animOpen.From = 0;
                animOpen.To = 200;

                animClose = new DoubleAnimation();
                Storyboard.SetTargetProperty(animClose, new PropertyPath("Height"));
                animClose.Duration = new Duration(duration);
                animClose.To = 0;

                animSwapOpen = new DoubleAnimation();
                Storyboard.SetTargetProperty(animSwapOpen, new PropertyPath("Height"));
                animSwapOpen.Duration = new Duration(duration);
                animSwapOpen.From = 0;
                animSwapOpen.To = 200;

                animSwapClose = new DoubleAnimation();
                Storyboard.SetTargetProperty(animSwapClose, new PropertyPath("Height"));
                animSwapClose.Duration = new Duration(duration);
                animSwapClose.To = 0;

                sbOpenPanel = new Storyboard();
                sbOpenPanel.Children.Add(animOpen);
                sbOpenPanel.Completed += new EventHandler(sbOpenPanel_Completed);

                sbClosePanel = new Storyboard();
                sbClosePanel.Children.Add(animClose);
                sbClosePanel.Completed += new EventHandler(sbClosePanel_Completed);

                sbSwapPanels = new Storyboard();
                sbSwapPanels.Children.Add(animSwapOpen);
                sbSwapPanels.Children.Add(animSwapClose);
                sbSwapPanels.Completed += new EventHandler(sbSwapPanels_Completed);

            }
        }

        #endregion

        #region Event Handlers
        /////////////////////////////////////////////////////////////
        // Event Handlers

        void headingCrtl_ExpandChange(object sender, EventArgs e)
        {
            if (sender is HeadingBarCtrl)
            {
                if (activeControl == null)
                {
                    if (setActiveControl(sender))
                    {
                        Storyboard.SetTarget(sbOpenPanel, activeControl.userControl);
                        animOpen.To = Math.Max(0, getGridFreeHeight() + activeControl.userControl.ActualHeight);

                        activeControl.gridRow.Height = _gridRowHeightAuto;
                        activeControl.userControl.Visibility = Visibility.Visible;
                        activeControl.userControl.VerticalAlignment = VerticalAlignment.Stretch;

                        activeControl.headingCrtl.IsArrowUp = true;
                        sbOpenPanel.Begin();
                    }
                }
                else if (sender == activeControl.headingCrtl)
                {
                    Storyboard.SetTarget(sbClosePanel, activeControl.userControl);
                    animClose.From = activeControl.userControl.ActualHeight;

                    activeControl.gridRow.Height = _gridRowHeightAuto;

                    activeControl.headingCrtl.IsArrowUp = false;
                    sbClosePanel.Begin();
                }
                else
                {
                    lastControl = activeControl;
                    if (setActiveControl(sender))
                    {
                        Storyboard.SetTarget(sbSwapPanels.Children[0], activeControl.userControl);
                        Storyboard.SetTarget(sbSwapPanels.Children[1], lastControl.userControl);

                        animSwapOpen.To = Math.Max(0, getGridFreeHeight() + lastControl.userControl.ActualHeight + activeControl.userControl.ActualHeight);
                        animSwapClose.From = Math.Max(0, lastControl.userControl.ActualHeight);

                        lastControl.gridRow.Height = _gridRowHeightAuto;
                        activeControl.gridRow.Height = _gridRowHeightAuto;
                        activeControl.userControl.Visibility = Visibility.Visible;
                        activeControl.userControl.VerticalAlignment = VerticalAlignment.Stretch;

                        activeControl.headingCrtl.IsArrowUp = true;
                        lastControl.headingCrtl.IsArrowUp = false;
                        sbSwapPanels.Begin();
                    }

                }
            }
        }


        void sbOpenPanel_Completed(object sender, EventArgs e)
        {
            activeControl.userControl.VerticalAlignment = VerticalAlignment.Stretch;
            activeControl.gridRow.Height = _gridRowHeightStar;
            sbOpenPanel.Stop();
        }
        void sbClosePanel_Completed(object sender, EventArgs e)
        {
            activeControl.userControl.Visibility = Visibility.Collapsed;
            activeControl.gridRow.Height = _gridRowHeightAuto;
            activeControl = null;
            sbClosePanel.Stop();
        }
        void sbSwapPanels_Completed(object sender, EventArgs e)
        {
            activeControl.userControl.VerticalAlignment = VerticalAlignment.Stretch;
            activeControl.gridRow.Height = _gridRowHeightStar;

            lastControl.userControl.Visibility = Visibility.Collapsed;
            lastControl.gridRow.Height = _gridRowHeightAuto;

            sbSwapPanels.Stop();
        }

        #endregion

        #region Helpers
        /////////////////////////////////////////////////////////////
        // Helpers


        private bool setActiveControl(object header)
        {
            if (header is HeadingBarCtrl)
            {
                HeadingBarCtrl headingCtrl = (HeadingBarCtrl)header;
                foreach (SwapPanelControllerParams control in this.controls)
                {
                    if (control.headingCrtl == headingCtrl)
                    {
                        this.activeControl = control;
                        return true;
                    }
                }
            }
            return false;
        }


        private double getGridFreeHeight()
        {
            if (activeControl != null && activeControl.userControl != null && activeControl.userControl.Parent is Grid)
            {
                Grid grid = (Grid)activeControl.userControl.Parent;

                double gridHeight = grid.ActualHeight;
                double totRowHeight = 0;
                foreach (RowDefinition row in grid.RowDefinitions)
                {
                    totRowHeight += row.ActualHeight;
                }
                return Math.Max(0, gridHeight - totRowHeight);
            }
            return 0;
        }

        #endregion

    }

    /////////////////////////////////////////////////////////////
    /////////////////////////////////////////////////////////////
    // Parameter Class

    public class SwapPanelControllerParams
    {
        public UserControl userControl { get; set; }
        public RowDefinition gridRow { get; set; }
        public HeadingBarCtrl headingCrtl { get; set; }

        public SwapPanelControllerParams()
        {
        }

        public SwapPanelControllerParams(UserControl UserControl, HeadingBarCtrl HeadingCtrl)
        {
            this.userControl = UserControl;
            this.headingCrtl = HeadingCtrl;

            if (UserControl != null && UserControl.Parent is Grid)
            {
                Grid parent = (Grid)UserControl.Parent;
                int row = Grid.GetRow(UserControl);
                this.gridRow = parent.RowDefinitions[row];
            }

        }
    }
}
